package com.fy.qu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fy.core.consts.QuAnswerConstant;
import com.fy.core.consts.QuTypeConstant;
import com.fy.core.dto.PageDto;
import com.fy.core.enums.ApiErrorEnum;
import com.fy.core.exception.ServiceException;
import com.fy.core.vo.ApiRest;
import com.fy.core.vo.PageResult;
import com.fy.qu.dto.QuSearchDto;
import com.fy.qu.entity.Qu;
import com.fy.qu.entity.QuAnswer;
import com.fy.qu.entity.QuRepo;
import com.fy.qu.mapper.QuAnswerMapper;
import com.fy.qu.mapper.QuMapper;
import com.fy.qu.mapper.QuRepoMapper;
import com.fy.qu.dto.QuAddDto;
import com.fy.qu.service.QuService;
import com.fy.repo.mapper.RepoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 问题题目 服务实现类
 * </p>
 *
 * @author hxd
 * @since 2023-06-12
 */
@Service
@Slf4j
public class QuServiceImpl extends ServiceImpl<QuMapper, Qu> implements QuService {

    @Autowired
    private QuRepoMapper quRepoMapper;
    @Autowired
    private QuAnswerMapper quAnswerMapper;

    @Autowired
    private RepoMapper repoMapper;

    @Override
    public PageResult<Qu> findPage(PageDto<QuSearchDto> pageDto) {
        IPage<Qu> page=new Page<>(pageDto.getNow(), pageDto.getSize());
        IPage<Qu> pageInfo=this.baseMapper.findPage(page,pageDto.getWhere());

        PageResult<Qu> pageResult=new PageResult<>();
        pageResult.setPages(pageInfo.getPages());
        pageResult.setList(pageInfo.getRecords());
        pageResult.setTotal(pageInfo.getTotal());
        return pageResult;
    }

    @Override
    @Transactional
    public ApiRest save(QuAddDto quAddDto) {

        //1:参数校验
        checkData(quAddDto);

        //2:插入 qu表
        Qu qu =new Qu();
        if(quAddDto.getId() == null){
            qu.setId(IdWorker.getIdStr());
        }else {
            qu.setId(quAddDto.getId());
        }

        qu.setCreateTime(new Date());
        qu.setUpdateTime(new Date());

        BeanUtil.copyProperties(quAddDto,qu,true);
        this.baseMapper.insert(qu);

        //3:插入 qu_repo
        String[] repoIds = quAddDto.getRepoIds();
        //数组没有刘，所有转list
        List<QuRepo> quRepoList = Arrays.asList(repoIds).stream().map(repoId -> {

            QuRepo quRepo = new QuRepo();
            quRepo.setId(IdWorker.getIdStr());
            quRepo.setRepoId(repoId);
            quRepo.setQuId(qu.getId());
            quRepo.setQuType(qu.getQuType());
            return quRepo;
        }).collect(Collectors.toList());
        //循环遍历插入
        quRepoList.forEach(item ->{
            quRepoMapper.insert(item);
        });

        //4:插入 qu_answer
        List<QuAnswer> answerList = quAddDto.getAnswerList();
        answerList.forEach(item->{
            item.setId(IdWorker.getIdStr());
            item.setQuId(qu.getId());
            quAnswerMapper.insert(item);
        });

        //5:更新repo（题目数量）
        for(String repoId : quAddDto.getRepoIds()){
            repoMapper.updateCountByRepoId(repoId);
        }

        log.info("{}题目录入成功",new Date());
        return ApiRest.success("题目录入成功");
    }

    @Override
    public ApiRest findById(String quId) {

        QuAddDto quAddDto =new QuAddDto();
        Qu qu = this.baseMapper.selectById(quId);
        BeanUtil.copyProperties(qu,quAddDto,true);
        List<String> repoIds = quRepoMapper.findRepoIdByQuId(quId);
        String[] repoIdsArr = repoIds.toArray(new String[repoIds.size()]);
        quAddDto.setRepoIds(repoIdsArr);

        List<QuAnswer> answerList = quAnswerMapper.findAnswerById(quId);
        quAddDto.setAnswerList(answerList);

        return ApiRest.success("查找成功",quAddDto);
    }

    @Override
    @Transactional
    public ApiRest update(QuAddDto addDto) {
//        checkData(addDto);
        delete(addDto.getId());
        save(addDto);

        return ApiRest.success("修改成功");
    }

    @Override
    public ApiRest delete(String quId) {

        QueryWrapper<QuRepo> queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("qu_id",quId);
        List<QuRepo> quRepos = quRepoMapper.selectList(queryWrapper);

        //1:删除 qu
        this.baseMapper.deleteById(quId);

        //2:删除 qu_answer
        UpdateWrapper updateWrapper =new UpdateWrapper<>();
        updateWrapper.eq("qu_id",quId);
        quAnswerMapper.delete(updateWrapper);

        //3:删除 qu_repo
        quRepoMapper.delete(updateWrapper);

        //4:更新数量
        for(QuRepo quRepo:quRepos){
            repoMapper.updateCountByRepoId(quRepo.getRepoId());
        }
        return ApiRest.success("题目删除成功");
    }

    @Override
    public ApiRest batchDelete(List<Qu> qus) {

        for(Qu qu : qus){
            delete(qu.getId());
        }
        return ApiRest.success("批量删除成功");
    }


    /**
     * 参数校验
     * @param quAddDto
     */
    private void checkData(QuAddDto quAddDto) {

        if (quAddDto == null) {
            throw new ServiceException(ApiErrorEnum.PARAM_SHOULD_NOT_NULL);
        }


        if (StringUtils.isEmpty(quAddDto.getContent())) {
            throw new ServiceException(ApiErrorEnum.QU_CONTENT_IS_NULL);
        }

        if (CollectionUtils.isEmpty(Arrays.asList(quAddDto.getRepoIds()))) {
            throw new ServiceException(ApiErrorEnum.QU_REPO_ATLEAST_ONE);
        }

        List<QuAnswer> answers = quAddDto.getAnswerList();


        if (quAddDto.getQuType() != QuTypeConstant.JDT && CollectionUtils.isEmpty(answers)) {
            throw new ServiceException(ApiErrorEnum.QU_HAS_ANSWER);
        }


        int trueCount = 0;
        for (QuAnswer a : answers) {


            if (StringUtils.isEmpty(a.getContent())) {
                throw new ServiceException(ApiErrorEnum.QU_ANSWER_CONTEXT_IS_NULL);
            }

            if (a.getIsRight() == QuAnswerConstant.RIGHT) {
                trueCount += 1;
            }
        }

        if (trueCount == 0) {
            throw new ServiceException(ApiErrorEnum.QU_ANSWER_HAS_ONE);
        }


        //单选题
        if (quAddDto.getQuType() ==  QuTypeConstant.RADIO  && trueCount > 1) {
            throw new ServiceException(ApiErrorEnum.QU_RADIO_ANSWER_HAS_ONE);
        }
    }

}
